#include <chrono>
#include <iostream>
#include <vector>
#include <memory>                                                                   

template <class T>
size_t EstimateMemoryUsage(const std::shared_ptr<T>& ptr) {
  auto use_count = ptr.use_count();
  if (use_count == 0) {
    return 0;
  }
  // Model shared_ptr after libc++,
  // see __shared_ptr_pointer from include/memory
  struct SharedPointer {
    void* vtbl;
    long shared_owners;
    long shared_weak_owners;
    T* value;
  };
  // If object of size S shared N > S times we prefer to (potentially)
  // overestimate than to return 0.
  return sizeof(SharedPointer) + ( sizeof(T) + (use_count - 1)) / use_count;
}

class A{
    int a;
    int b;
    int c;
};

int main()
{
    auto p = std::make_shared<A>();
    std::cout << EstimateMemoryUsage( p ) << std::endl;
    auto q = p;
    auto r = p;
    auto s = p;
    std::cout << q.use_count() << std::endl;
    std::cout << EstimateMemoryUsage( q ) << std::endl;
}